import "./code-mirror.scss";
import codemirror from 'codemirror';
import jsYaml from 'js-yaml';
import jsDocker from './docker-lint/linter.js'

class Drct {
    constructor() {
        this.require = 'ngModel';
        this.replace = true;
        this.restrict = 'E';
        this.template = '<div><textarea></textarea></div>';
    }

    link(scope, element, attr, ngModel) {
        var config = {mode: attr.mode, lineNumbers: true};
        switch (attr.mode) {
            case 'text/x-yaml':
                config.gutters = ['CodeMirror-lint-markers'];
                config.lint = {
                    getAnnotations: function (text, opt, _cm) {
                        opt.hasErr = false;
                        var found = [];
                        try {
                            jsYaml.safeLoadAll(text, function() {});
                        } catch (e) {
                            opt.hasErr = true;
                            var loc = e.mark;
                            found.push(loc ? {
                                from: codemirror.Pos(loc.line < _cm.lineCount() ? loc.line : _cm.lineCount()-1, loc.column),
                                to: codemirror.Pos(loc.line < _cm.lineCount() ? loc.line : _cm.lineCount()-1, loc.column),
                                message: e.message
                            } : {
                                from: codemirror.Pos(0, 0),
                                to: codemirror.Pos(0, 0),
                                message: e.message
                            });
                        }
                        return found;
                    }
                };
                break;
            case 'text/x-dockerfile':
                config.gutters = ['CodeMirror-lint-markers'];
                config.lint = {
                    getAnnotations: function (text, opt) {
                        opt.hasErr = false;
                        var found = [];
                        angular.forEach(jsDocker.validate(text).error.data, function (data) {
                            found.push({
                                from: codemirror.Pos(data.line - 1, 0),
                                to: codemirror.Pos(data.line - 1, 0),
                                message: data.message
                            })
                        });
                        if (found.length) opt.hasErr = true;
                        return found;
                    }
                };
                break;
        }

        var cm = codemirror.fromTextArea(element.find('textarea')[0], config);

        scope.$evalAsync(function () {
            ngModel.$setViewValue(cm);
        });
    }

    static factory() {
        return new Drct();
    }
}

export default Drct;